package dir_sync;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Vector;

/**
 * 目录比较同步助手。
 */
public class DirCompare {

    private JFrame frame;
    /**
     * 目标目录BBB
     */
    private JTextField dstDirTextField;
    /**
     * 源目录AAA
     */
    private JTextField srcDirTextField;

    /**
     * @return frame
     */
    public JFrame getFrame() {
        return frame;
    }

    /**
     * 底部状态条
     */
    private JLabel statusLabel;
    /**
     * 比较目录返回集合AAA
     */
    private final Vector<File> srcChangedFiles = new Vector<>();
    /**
     * 被比较目录返回集合BBB
     */
    private final Vector<File> vector_b = new Vector<>();
    private final DefaultListModel<String> listModelSrc = new DefaultListModel<>();
    private final DefaultListModel<String> listModelDst = new DefaultListModel<>();

    public static boolean isComparing = false;
    private Thread compareThread;
    private JButton compareButton;

    private JCheckBox onlyShowDiffCheckBox;
    private JCheckBox bothDiffCheckBox;
    private JTextField limitTF;
    private JButton syncCopyButton;

    /**
     * Create the application.
     */
    public DirCompare() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {

        frame = new JFrame();
        try {
            String kk = UIManager.getSystemLookAndFeelClassName();// 获得当前系统样式名称字符串。
            UIManager.setLookAndFeel(kk);// 加载样式。
            SwingUtilities.updateComponentTreeUI(frame);// 应用给当前的窗口。
        } catch (Exception e) {
            System.err.println("ERROR: " + e.getMessage());
        }
        frame.setBounds(280, 250, 1000, 800);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(true);
        frame.setTitle("目录比较工具 " + Config.VERSION);
        Container bigPanel = frame.getContentPane();

        JPanel topPanel = new JPanel();
        topPanel.setBorder(new EmptyBorder(15, 15, 10, 15)); // 添加四周的间距
        topPanel.setLayout(new BorderLayout(10, 10));

        JPanel userInputPanel = createTopUserInputPanel();
        JPanel userButtonPanel = createTopUserButtonPanel();

        topPanel.add(userInputPanel, BorderLayout.NORTH);
        topPanel.add(userButtonPanel, BorderLayout.SOUTH);
        bigPanel.add(topPanel, BorderLayout.NORTH);

        JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
        bigPanel.add(tabbedPane, BorderLayout.CENTER);

        JScrollPane srcScrollPane = new JScrollPane();
        tabbedPane.addTab("原始目录", null, srcScrollPane, null);


        JList<String> srcJList = new JList<>(this.listModelSrc);
        srcScrollPane.setViewportView(srcJList);

        JScrollPane dstScrollPane = new JScrollPane();
        tabbedPane.addTab("目标目录", null, dstScrollPane, null);

        JList<String> dstJList = new JList<>(listModelDst);
        dstScrollPane.setViewportView(dstJList);

        statusLabel = new JLabel("请选择原始目录和要比较的新目录.....");
        bigPanel.add(statusLabel, BorderLayout.SOUTH);

    }

    private JPanel createTopUserInputPanel() {
        JPanel userInputPanel = new JPanel();
        userInputPanel.setLayout(new GridLayout(2, 1, 20, 20));

        JPanel srcPanel = new JPanel();
        srcPanel.setLayout(new BorderLayout(10, 10));
        srcPanel.add(new JLabel("源始目录: "), BorderLayout.WEST);

        srcDirTextField = new JTextField();
        srcDirTextField.setEditable(false);
        srcDirTextField.setEnabled(false);
        srcDirTextField.setToolTipText("原始目录地址栏");
        srcDirTextField.setText("");
        srcPanel.add(srcDirTextField, BorderLayout.CENTER);


        JButton srcButton = new JButton("选择...");
        srcButton.setToolTipText("请选择原始目录。");
        srcButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                // 获取源目录
                JFileChooser chooser1 = new JFileChooser();
                chooser1.setToolTipText("请选择源目录");
                chooser1.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                String lastSelectedDir = srcDirTextField.getText();
                if (lastSelectedDir != null && !lastSelectedDir.isEmpty()) {
                    chooser1.setCurrentDirectory(new File(lastSelectedDir));
                }
                int rt = chooser1.showOpenDialog(frame);
                if (rt == JFileChooser.APPROVE_OPTION) {
                    srcDirTextField.setText(chooser1.getSelectedFile().getPath());
                    statusLabel.setText("源目录：" + chooser1.getSelectedFile().getPath()
                            + "请选择目标目录！");

                }
            }
        });
        srcPanel.add(srcButton, BorderLayout.EAST);


        JPanel dstPanel = new JPanel();
        dstPanel.setLayout(new BorderLayout(10, 10));
        dstPanel.add(new JLabel("目标目录: "), BorderLayout.WEST);

        dstDirTextField = new JTextField();
        dstDirTextField.setEditable(false);
        dstDirTextField.setEnabled(false);
        dstDirTextField.setToolTipText("目标目录地址栏");
        dstDirTextField.setText("");
        dstDirTextField.setColumns(60);
        dstPanel.add(dstDirTextField, BorderLayout.CENTER);

        JButton dstButton = new JButton("选择...");
        dstButton.setToolTipText("请选择目标目录。");
        dstButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // 选择目标目录
                JFileChooser chooser2 = new JFileChooser();
                chooser2.setToolTipText("选择目标目录");
                chooser2.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

                String lastSelectedDir = dstDirTextField.getText();
                if (lastSelectedDir != null && !lastSelectedDir.isEmpty()) {
                    chooser2.setCurrentDirectory(new File(lastSelectedDir));
                }
                int rt = chooser2.showOpenDialog(frame);
                if (rt == JFileChooser.APPROVE_OPTION) {
                    dstDirTextField.setText(chooser2.getSelectedFile().getPath());
                    statusLabel.setText("目标目录：" + chooser2.getSelectedFile().getPath()
                            + "如果两个目录都已经选择好，可以开始比较了o(∩_∩)o ");
                }
            }
        });
        dstPanel.add(dstButton, BorderLayout.EAST);

        userInputPanel.add(srcPanel);
        userInputPanel.add(dstPanel);

        return userInputPanel;
    }

    private JPanel createTopUserButtonPanel() {
        // 用户操作面板
        JPanel buttonPanel = new JPanel();

        buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 15, 5));


        bothDiffCheckBox = new JCheckBox("双向比较");
        bothDiffCheckBox.setToolTipText("默认只支持以源目录为主的单向比较");
        bothDiffCheckBox.setSelected(false);
        buttonPanel.add(bothDiffCheckBox);


        buttonPanel.add(new JLabel("限制目录深度: "));

        limitTF = new JTextField();
        limitTF.setColumns(10);
        limitTF.setText("" + Config.SCAN_DEEP);
        limitTF.setToolTipText("如果想无限制深度比较，请输入-1");
        buttonPanel.add(limitTF);

        onlyShowDiffCheckBox = new JCheckBox("仅显示不同");
        onlyShowDiffCheckBox.setToolTipText("如果勾选，则相同内容将不显示");
        onlyShowDiffCheckBox.setSelected(true);
        buttonPanel.add(onlyShowDiffCheckBox);

        compareButton = new JButton("开始比较");
        compareButton.setToolTipText("点击开始同步原始目录与目标目录中结构不同。");
        compareButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                synchronized (DirCompare.class) {
                    if (isComparing) {
                        stopCompare();
                    } else {
                        String src = srcDirTextField.getText().trim();
                        String dst = dstDirTextField.getText().trim();

                        // 判断目录为空！
                        if (src.isEmpty()) {
                            showMessage("请选择原始目录");
                        } else if (dst.isEmpty()) {
                            showMessage("请选择目标目录");
                        } else if (src.equals(dst)) {
                            showMessage("两个目录不能相同");
                        } else {
                            // 开始比较目录及文件。
                            startCompare();
                        }
                    }
                }
            }
        });
        buttonPanel.add(compareButton);

        syncCopyButton = new JButton("同步文件");
        syncCopyButton.setToolTipText("点击开始同步目录中的不同文件与目录。");
        syncCopyButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                startSyncCopy();
            }
        });
        buttonPanel.add(syncCopyButton);

        return buttonPanel;

    }


    /**
     * 开始比较目录
     */
    public void startCompare() {
        this.syncCopyButton.setEnabled(false);
        this.listModelSrc.clear();
        this.listModelDst.clear();
        srcChangedFiles.clear();

        isComparing = true;
        int scanDeep;
        try {
            scanDeep = Integer.parseInt(limitTF.getText());
        } catch (Exception e) {
            showMessage("限制目录深度只能是正整数！");
            return;
        }

        // 使用SwingWorker来避免界面卡顿
        DirCompareWork task = new DirCompareWork(listModelSrc, listModelDst,
                compareButton, srcDirTextField, dstDirTextField, onlyShowDiffCheckBox.isSelected(),
                scanDeep, bothDiffCheckBox.isSelected(), statusLabel, syncCopyButton, srcChangedFiles);
        compareThread = new Thread(task);
        compareThread.start();
    }


    /**
     * 停止比较目录
     */
    public void stopCompare() {
        if (compareThread != null && compareThread.isAlive()) {
            compareThread.interrupt();
            isComparing = false;
            compareThread = null;
        }
    }


    private void showMessage(String mg) {
        JOptionPane.showMessageDialog(frame, mg, "提示", JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * 创建线程开始复制文件
     */
    private void startSyncCopy() {
        this.compareButton.setEnabled(false);
        this.syncCopyButton.setEnabled(false);
        // 开始同步文件 创建复制同步窗口，获取相关对象，发送需要同步的数据到复制窗口。

        if (!srcChangedFiles.isEmpty()) {
            System.out.println("开始同步文件 创建复制同步窗口，获取相关对象，发送需要同步的数据到复制窗口。" + srcChangedFiles.size() + vector_b.size());
            StartCopy sCopy = new StartCopy(this.compareButton, this.syncCopyButton);
            sCopy.setV_a(srcChangedFiles);//
            sCopy.setV_b(vector_b);
            sCopy.setDir_a(srcDirTextField.getText());
            sCopy.setDir_b(dstDirTextField.getText());
            statusLabel.setText("准备开始同步文件o(∩_∩o");
        } else {
            showMessage("没有需要同步的文件，或请先进行文件比较，点击开始比较按钮!");
            this.compareButton.setEnabled(true);
        }

    }
}
